//! /usr/bin/env node postcss/watch-case.mjs --watch /*error This file needs no hashbang.*/
// @ts-check
import fs from "node:fs/promises";
import { dirname, join, relative } from "node:path";
import { watch as _watch } from "chokidar"; // 用于文件监听
import postcss from "postcss";
import { p2 } from "../../shared/p2.mjs";

const CONTEXT_PATH = p2("postcss");

class PostCSSProcessor {
  constructor(options = {}) {
    this.options = {
      srcDir: p2("postcss"),
      distDir: p2("postcss/dist"),
      minify: true,
      sourceMap: true,
      ...options,
    };
  }

  /**
   * 处理单个 CSS 文件
   * @param {string} filename
   * @returns {Promise<import("postcss").Result<import("postcss").Root>>}
   */
  async processFile(filename) {
    const inputPath = join(this.options.srcDir, filename);
    const outputPath = join(this.options.distDir, filename);

    try {
      const css = await fs.readFile(inputPath, "utf8");

      const result = await postcss().process(css, {
        from: inputPath,
        to: outputPath,
        map: this.options.sourceMap
          ? { inline: false, annotation: true }
          : false,
      });

      // 确保输出目录存在
      const outputDir = dirname(outputPath);
      try {
        await fs.access(outputDir);
      } catch {
        await fs.mkdir(outputDir, { recursive: true });
      }

      // 写入 CSS 文件
      await fs.writeFile(outputPath, result.css);

      // 写入 source map
      if (this.options.sourceMap && result.map) {
        await fs.writeFile(`${outputPath}.map`, result.map.toString());
      }

      console.log(`✅ 处理完成: ${filename}`);
      return result;
    } catch (error) {
      console.error(`❌ 处理 ${filename} 时出错:`, error);
      throw error;
    }
  }

  /**
   * 处理所有 CSS 文件
   * @returns {Promise<import("postcss").Result<import("postcss").Root>[] | undefined>}
   */
  async processAll() {
    console.log("🔍 扫描 CSS 文件...");

    try {
      const files = (await fs.readdir(this.options.srcDir)).filter((file) =>
        file.endsWith(".css"),
      );

      console.log(`📁 找到 ${files.length} 个 CSS 文件`);

      const results = [];
      for (const file of files) {
        results.push(await this.processFile(file));
      }

      console.log("🎉 所有文件处理完成!");
      return results;
    } catch (error) {
      console.error("❌ 处理文件时出错:", error);
    }
  }

  // 监听文件变化
  watch() {
    console.log("👀 开始监听文件变化...");

    const watcher = _watch(join(this.options.srcDir, "**/*.css"), {
      ignoreInitial: true,
    });

    watcher.on("change", async (filePath) => {
      const filename = relative(this.options.srcDir, filePath);
      console.log(`🔄 文件发生变化: ${filename}`);
      await this.processFile(filename);
    });

    watcher.on("add", async (filePath) => {
      const filename = relative(this.options.srcDir, filePath);
      console.log(`➕ 新增文件: ${filename}`);
      await this.processFile(filename);
    });

    return watcher;
  }
}

// 使用示例
/**
 * @returns {Promise<void>}
 */
async function watch() {
  const processor = new PostCSSProcessor({
    srcDir: p2("postcss"),
    distDir: p2("postcss/dist"),
    minify: true,
    sourceMap: true,
  });

  // 处理所有文件
  await processor.processAll();

  // 如果需要监听模式，取消注释下面这行
  // processor.watch();
}

if (import.meta.main) {
  // 命令行参数处理
  const args = process.argv.slice(2);
  if (
    process.env.WATCH ||
    process.env.WATCH_MODE ||
    args.includes("-w") ||
    args.includes("--watch")
  ) {
    const processor = new PostCSSProcessor();
    processor.processAll().then(() => processor.watch());
  } else {
    watch();
  }
}
